﻿using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.Debugger.Interop;
using System.Collections.ObjectModel;

namespace UDKDevKitVSXDebugEngine
{
    // This class manages breakpoints for the engine. 
    class BreakpointManager
    {
        private Engine engine;
        private IList<PendingBreakpoint> pendingBreakpoints;
        private object pendingBreakpointsLocker = new object();

        public BreakpointManager(Engine engine)
        {
            this.engine = engine;
            this.pendingBreakpoints = new List<PendingBreakpoint>();
        }

        // A helper method used to construct a new pending breakpoint.
        public void CreatePendingBreakpoint(IDebugBreakpointRequest2 pBPRequest, out IDebugPendingBreakpoint2 ppPendingBP)
        {
            lock (pendingBreakpointsLocker)
            {
                PendingBreakpoint pendingBreakpoint = new PendingBreakpoint(pBPRequest, engine, this);
                ppPendingBP = (IDebugPendingBreakpoint2)pendingBreakpoint;
                this.pendingBreakpoints.Add(pendingBreakpoint);
            }
        }

        // Called from the engine's detach method to remove the debugger's breakpoint instructions.
        public void ClearBoundBreakpoints()
        {
            lock (pendingBreakpointsLocker)
            {
                foreach (var pendingBreakpoint in this.pendingBreakpoints)
                {
                    pendingBreakpoint.ClearBoundBreakpoints();
                }
            }
        }

        internal IList<BoundBreakpoint> FindAllBoundExceptions()
        {
            lock (pendingBreakpointsLocker)
            {
                var boundBreakpointsToSend = new List<BoundBreakpoint>();

                // todo: finish
                foreach (var paendingBreakpoint in this.pendingBreakpoints)
                {
                    var documentContext = this.engine.DebugContext.DocumentContext;
                    boundBreakpointsToSend.AddRange(
                        paendingBreakpoint.GetBoundBreakpointsBelongTo(
                            documentContext.ClassName,
                            documentContext.CurrentDebuggingStatementLine));
                }

                return boundBreakpointsToSend;
            }
        }
    }
}
